#include "tcp_server.h"

TcpServer::TcpServer(QObject *parent) : QTcpServer(parent)
{
   // connect(this, &QTcpServer::newConnection, this, &TcpServer::newConnection);
}

TcpServer::~TcpServer()
{
    qDebug()<<"关闭tcp服务器";
    stop();

    foreach (QThread* thread, clientsThreads) {
        thread->quit();
        //主线程等待子线程结束
        thread->wait();
        delete thread;

        //等同于上面一句
        //或者在构造函数的位置添加connect(thread, &QThread::finished, thread, &QObject::deleteLater);
    }

}

void TcpServer::incomingConnection(qintptr socketDescriptor)
{

    qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
    qRegisterMetaType<qintptr>("qintptr");

    QTcpSocket *socket = new QTcpSocket;
    socket->setSocketDescriptor(socketDescriptor);


    //不加this，客户端断开连接会后闪退
    TcpClient *client = new TcpClient(socket);


    //为每个新连接的套接字建立线程
    QThread *clientThread = new QThread(this);
    client->moveToThread(clientThread);
    connect(clientThread, &QThread::finished, this, &TcpClient::deleteLater);
    clientThread->start();

    //记录套接字
    m_handleTcpClientHash[socketDescriptor] = client;
    m_handleThreadHash[socketDescriptor] = clientThread;


    //关闭tcp服务器
    connect(client, &TcpClient::clientDisconnected, this, &TcpServer::disconnected);

    //传递客户端套接字发送的数据
    //connect(client, &TcpClient::sendData, this, &TcpServer::sendData);
    connect(client, static_cast<void (TcpClient::*)(const QString &, int port, const QString &)>(&TcpClient::sendData),
            this, &TcpServer::sendData);

    //转发收到的数据
    connect(client, &TcpClient::receiveData, this, &TcpServer::receiveData);

    //发送客户端成功连接的信号
    emit clientConnected(client->getIP(), client->getPort());


    // QString ip = client->getIP();
    // int port = client->getPort();
    // emit clientConnected(ip, port);
    emit sendData(client->getIP(), client->getPort(), "客户端上线");

    //连接后加入链表
    clients.append(client);
    clientsThreads.append(clientThread);
}


void TcpServer::newConnection()
{
    QTcpSocket *socket = this->nextPendingConnection(); //结束子线程

    //不加this，客户端断开连接会闪退
    TcpClient *client = new TcpClient(socket, this);

    //为每个新连接的套接字建立线程
    QThread *clientThread = new QThread;
    client->moveToThread(clientThread);
    connect(clientThread, &QThread::finished, this, &TcpClient::deleteLater);
    clientThread->start();


    //关闭tcp服务器
   // connect(client, &TcpClient::clientDisconnected, this, &TcpServer::disconnected);
    connect(client, &TcpClient::clientDisconnected, this, &TcpServer::disconnected);

    //传递客户端套接字发送的数据
    //connect(client, &TcpClient::sendData, this, &TcpServer::sendData);
    connect(client, static_cast<void (TcpClient::*)(const QString &, int port, const QString &)>(&TcpClient::sendData),
            this, &TcpServer::sendData);

    //转发收到的数据
    connect(client, &TcpClient::receiveData, this, &TcpServer::receiveData);

    //发送客户端成功连接的信号
    emit clientConnected(client->getIP(), client->getPort());


    // QString ip = client->getIP();
    // int port = client->getPort();
    // emit clientConnected(ip, port);
    emit sendData(client->getIP(), client->getPort(), "客户端上线");

    //连接后加入链表
    clients.append(client);
    clientsThreads.append(clientThread);
}

// void TcpServer::disconnected()
// {
//     qDebug()<<"客户端下线";
//     TcpClient *client = (TcpClient *)sender();
//     qDebug()<<"客户端下线1";
//     QString ip = client->getIP();
//     int port = client->getPort();
//     qDebug()<<"客户端下线2";
//     emit clientDisconnected(ip, port);
//     emit sendData(ip, port, "客户端下线");

//     // client->m_socket->deleteLater();
//     // client->deleteLater();

//     //断开连接后从链表中移除
//     clients.removeOne(client);



// }

void TcpServer::disconnected(qintptr socketDescriptor)
{
    qDebug()<<"客户端下线";
    TcpClient *client = (TcpClient *)sender();
    QString ip = client->getIP();
    int port = client->getPort();
    qDebug()<<"客户端下线的信息"<<ip<<" "<<port;

    emit clientDisconnected(ip, port);
    emit sendData(ip, port, "客户端下线");

    //断开连接后从链表中移除

    clients.removeOne(client);

    // m_handleTcpClientHash.remove(socketDescriptor);

    //下面的代码会让客户端断开连接后，会退出
    // client->m_socket->deleteLater();
    // client->deleteLater();

    // m_handleThreadHash[socketDescriptor]->quit();
    // m_handleThreadHash[socketDescriptor]->wait();
}

// void TcpServer::disconnected(qintptr socketDescriptor)
// {
//     qDebug()<<"客户端下线";
//     TcpClient *client = (TcpClient *)sender();
//     QString ip = client->getIP();
//     int port = client->getPort();
//     emit clientDisconnected(ip, port);
//     emit sendData(ip, port, "客户端下线");

//     //断开连接后从链表中移除
//     clients.removeOne(client);
// }



bool TcpServer::start(QString ip, int port)
{
    bool ok = listen(QHostAddress(ip), port);
    return ok;
}

void TcpServer::stop()
{
    remove();
    this->close();
}

void TcpServer::writeData(const QString &ip, int port, const QString &data)
{
    foreach (TcpClient *client, clients) {
        if (client->getIP() == ip && client->getPort() == port) {
            client->sendData(data);
            break;
        }
    }
}

void TcpServer::writeData(const QString &data)
{
    foreach (TcpClient *client, clients) {
        client->sendData(data);
    }
}

void TcpServer::remove(const QString &ip, int port)
{
    foreach (TcpClient *client, clients) {
        if (client->getIP() == ip && client->getPort() == port) {
            client->abort();
            break;
        }
    }
}

void TcpServer::remove()
{
    foreach (TcpClient *client, clients) {
        client->abort();
    }
}
